library("ggplot2")
library("dplyr")
Warning: package ‘dplyr’ was built under R version 4.1.2

Attaching package: ‘dplyr’

The following objects are masked from ‘package:stats’:

    filter, lag

The following objects are masked from ‘package:base’:

    intersect, setdiff, setequal, union

Hypergate takes in 1. an expression matrix 2. a vector of events to attempt to gate on - there are different ways to get these

interactive gating - try later Clustering - this is what I want to use

hypergate is the function to optomize gating strategies

xp = a numberic matrix encoding expression gate_vector a vector with a few unique values — this should be the cluster labels level specifies what value of gate vector togate upon


hg_output <- hypergate(xp = xm.t, gate_vector = cluster.labels, level = 'Astro1')
Error: vector memory exhausted (limit reached?)

I’ll need to downsample the seurat object

# try hypergate again on one group 
input.xm = as.matrix(GetAssayData(seu.down, slot = 'scale.data'))
xm.t <- t(input.xm)
cluster.labels <- as.vector(seu.down$labels)


hg_output <- hypergate(xp = xm.t, gate_vector = cluster.labels, level = 'Astro1')

Try checking the results


table(ifelse(gating_predicted, "Gated-in", "Gated-out"), ifelse(cluster.labels == 
    'Astro1', "Events of interest", "Others"))
           
            Events of interest Others
  Gated-in                 182     29
  Gated-out                 18   3458

Now we can see if each cell past parameters for the threshold for each AB

table(bm)
bm
FALSE  TRUE 
 8787 46518 

Plots some gates


plot_gating_strategy(gate = hg_output, xp = xm.t, gate_vector = cluster.labels, 
    level = 'Astro1', highlight = "firebrick3")
Warning in plot_gating_strategy(gate = hg_output, xp = xm.t, gate_vector = cluster.labels,  :
  path argument is missing, output won't be saved to file

Channel contributions

print(contributions)
   CD44_min HepaCAM_max    CD44_max    CD24_max   CD184_max   CD184_min    CD29_max   GLAST_max 
0.373515389 0.000000000 0.106921365 0.119328979 0.112535525 0.165172328 0.067667241 0.032497916 
   CD56_max   CD133_max    CD15_max    CD71_max    AQP4_max   CD133_min   GLAST_min 
0.061320445 0.028501912 0.031184675 0.024468298 0.012743090 0.004288837 0.004288837 

We could reoptimize using only the top 4 But right now I’ll leave this

hgate_pheno(hg_output)
[1] "CD44+, HepaCAM-, CD44-, CD24-, CD184-, CD184+, CD29-, GLAST-, CD56-, CD133-, CD15-, CD71-, AQP4-, CD133+, GLAST+"
hgate_rule(hg_output)
[1] "CD44 >= -0.07, HepaCAM <= 0.41, CD44 <= 1.22, CD24 <= 0.27, CD184 <= 0.56, CD184 >= -0.36, CD29 <= 0.29, GLAST <= 0.19, CD56 <= 0.22, CD133 <= 0.13, CD15 <= 0.24, CD71 <= 0.28, AQP4 <= 0.36, CD133 >= -0.67, GLAST >= -0.25"
hgate_info(hg_output)

I need to define the groups I want to gate first and then use this to gate them.


RidgePlot(seu.down, features = "CD44", log = TRUE )
Scale for 'x' is already present. Adding another scale for 'x', which will replace the existing scale.
Warning in self$trans$transform(x) : NaNs produced
Warning: Transformation introduced infinite values in continuous x-axis
Picking joint bandwidth of 0.134
Warning: Removed 32 rows containing non-finite values (stat_density_ridges).

RidgePlot(seu.down, features = "CD24", log = TRUE )
Scale for 'x' is already present. Adding another scale for 'x', which will replace the existing scale.
Warning in self$trans$transform(x) : NaNs produced
Warning: Transformation introduced infinite values in continuous x-axis
Picking joint bandwidth of 0.161
Warning: Removed 816 rows containing non-finite values (stat_density_ridges).

Regroup the similar for gating and remove mix cells that might confuse

table(seu.down$labels.groups)

               Mix      Neurons-CD24+        Astro-CD44+          RG-CD184+          RG-CD133+ 
                 0                400                400                400                400 
      Astro-Glast+        Endothelial      Neurons-CD56+ Neurons-CD24+CD56+              Oligo 
               400                400                400                400                400 
        Epithelial 
               400 

Hypergate on one group


for (cell in cell.types) {
  hg_output <- hypergate(xp = xm.t, gate_vector = cluster.labels, level = cell)
  gating_predicted = subset_matrix_hg(hg_output,xm.t)
  conf.table <- table(ifelse(gating_predicted, "Gated-in", "Gated-out"), ifelse(cluster.labels ==  cell, cell, "Others"))
  print(cell)
  print(conf.table)
  print(hgate_rule(hg_output))
}
[1] "Neurons-CD24+"
           
            Neurons-CD24+ Others
  Gated-in            353     42
  Gated-out            47   3558
[1] "CD24 >= 0.08, GLAST <= 0.32, CD71 <= 0.45, CD56 <= 1.09, CD133 <= 0.37, CD184 >= -1.06, CD15 <= 0.29, HepaCAM >= -0.44, CD184 <= 3.8, O4 <= 0.22, CD44 <= 3.85, CD29 <= 1.56, CD133 >= -0.82, CD140a <= 0.24"
[1] "Astro-CD44+"
           
            Astro-CD44+ Others
  Gated-in          251     37
  Gated-out         149   3563
[1] "CD44 >= -0.07, GLAST <= 0.16, CD24 <= 0.26, CD133 <= 0.37, CD15 <= 0.22, CD184 <= 0.62, CD184 >= -1.02, CD71 <= 0.51, CD56 <= 0.74, HepaCAM >= -0.41, CD71 >= -0.57, O4 <= 0.7, GLAST >= -0.23"
[1] "RG-CD184+"
           
            Others RG-CD184+
  Gated-in     116       313
  Gated-out   3484        87
[1] "CD184 >= -0.08, CD24 <= 0.04, GLAST <= 0.23, CD133 <= 0.53, CD15 <= 0.28, CD71 <= 0.32, HepaCAM >= -0.22, AQP4 <= 0.34, CD56 <= 1, O4 <= 0.19, CD56 >= -0.43, CD29 <= 1.46"
[1] "RG-CD133+"
           
            Others RG-CD133+
  Gated-in      26       349
  Gated-out   3574        51
[1] "CD133 >= 0.18, GLAST <= 0.6, O4 <= 0.29, CD29 <= 0.71, CD15 <= 0.23, CD184 >= -1.13, CD71 <= 1.12, CD184 <= 0.46, CD24 <= 2.88, AQP4 <= 0.58"
[1] "Astro-Glast+"
           
            Astro-Glast+ Others
  Gated-in           345     63
  Gated-out           55   3537
[1] "GLAST >= 0.14, CD15 <= 0.42, CD71 <= 0.47, CD56 <= 0.85, CD184 >= -1.01, CD133 <= 1.44, CD24 <= 1.86, O4 <= 0.06, CD184 <= 2.94, CD29 <= 1.72, AQP4 <= 1.21, CD56 >= -0.44, CD71 >= -0.6, CD44 <= 3.8"
[1] "Endothelial"
           
            Endothelial Others
  Gated-in          365     36
  Gated-out          35   3564
[1] "CD71 >= 0.33, CD15 <= 1.45, HepaCAM >= -0.32, CD56 <= 0.72, CD44 <= 1.66, AQP4 <= 1.61, CD184 <= 1.82, CD184 >= -2.18, CD133 <= 0.79, CD29 >= -0.61, CD133 >= -0.85, GLAST <= 4.54, O4 <= 0.96"
[1] "Neurons-CD56+"
           
            Neurons-CD56+ Others
  Gated-in            284     36
  Gated-out           116   3564
[1] "CD56 >= 0.36, O4 <= 0.57, CD15 <= 1.54, CD184 <= 0.58, CD184 >= -1.6, GLAST <= 2.17, CD71 <= 2.01, CD44 <= 1.67, CD24 <= 3.77, CD133 <= 2.37, HepaCAM >= -0.33, AQP4 <= 1.6"
[1] "Neurons-CD24+CD56+"
           
            Neurons-CD24+CD56+ Others
  Gated-in                 355     41
  Gated-out                 45   3559
[1] "CD15 >= 0.3, CD56 <= 2.54, O4 <= 0.13, AQP4 <= 1.27, CD184 >= -1.11, GLAST <= 4.49, CD71 <= 1.57, CD184 <= 3.87, CD24 <= 3.13, CD133 <= 3.38, HepaCAM >= -0.5, O4 >= -0.87"
[1] "Oligo"
           
            Oligo Others
  Gated-in    400      3
  Gated-out     0   3597
[1] "O4 >= 0.63, CD71 <= 1.59, CD140a >= -0.51"
[1] "Epithelial"
           
            Epithelial Others
  Gated-in         356     10
  Gated-out         44   3590
[1] "CD184 <= -1.08, O4 <= 0.3, CD71 <= 2.3, CD15 <= 0.53, CD133 <= 1.73"

Check results

hgate_rule(hg_output)
[1] "CD184 <= -1.08, O4 <= 0.3, CD71 <= 2.3, CD15 <= 0.53, CD133 <= 1.73"

Try with the input data

# try hypergate again on one group 
input.xm = as.matrix(GetAssayData(seu.down, slot = 'data'))
xm.t <- t(input.xm)
cluster.labels <- as.vector(seu.down$labels.groups)

#try all at once

cell.types <- c("Neurons-CD24+", "Astro-CD44+", "RG-CD184+", "RG-CD133+", "Astro-Glast+","Endothelial","Neurons-CD56+","Neurons-CD24+CD56+","Oligo","Epithelial")


# clearer output - should try make a summary of the accuray 

for (cell in cell.types) {
  hg_output <- hypergate(xp = xm.t, gate_vector = cluster.labels, level = cell)
  gating_predicted = subset_matrix_hg(hg_output,xm.t)
  conf.table <- table(ifelse(gating_predicted, "Gated-in", "Gated-out"), ifelse(cluster.labels ==  cell, cell, "Others"))
  print(cell)
  print(conf.table)
  print(hgate_rule(hg_output))
}
[1] "Neurons-CD24+"
           
            Neurons-CD24+ Others
  Gated-in            353     42
  Gated-out            47   3558
[1] "CD24 >= 10992.65, GLAST <= 5132.78, CD71 <= 13108.46, CD56 <= 37819.58, CD133 <= 8775.82, CD184 >= -3750.64, CD15 <= 17650.64, HepaCAM >= -2145.39, CD184 <= 39845.06, O4 <= 4552.8, CD44 <= 348666.71, CD29 <= 40777.53, CD133 >= -5403.91, CD140a <= 1365.04"
[1] "Astro-CD44+"
           
            Astro-CD44+ Others
  Gated-in          251     37
  Gated-out         149   3563
[1] "CD44 >= 53623.97, GLAST <= 3465.22, CD24 <= 15543.06, CD133 <= 8702.35, CD15 <= 15016.15, CD184 <= 11337.03, CD184 >= -3371.55, CD71 <= 14102.01, CD56 <= 29289.69, HepaCAM >= -1980.29, CD71 >= -5938.37, O4 <= 12036.54, GLAST >= -720.57"
[1] "RG-CD184+"
           
            Others RG-CD184+
  Gated-in     116       313
  Gated-out   3484        87
[1] "CD184 >= 5062.26, CD24 <= 9848.79, GLAST <= 4154.31, CD133 <= 10682.17, CD15 <= 17402.76, CD71 <= 10618.36, HepaCAM >= -798.72, AQP4 <= 28437.97, CD56 <= 35617.38, O4 <= 4113.55, CD56 >= 84.74, CD29 <= 38868.48"
[1] "RG-CD133+"
           
            Others RG-CD133+
  Gated-in      26       349
  Gated-out   3574        51
[1] "CD133 >= 6500.82, GLAST <= 8118.91, O4 <= 5626.44, CD29 <= 25215.51, CD15 <= 15633.17, CD184 >= -4352.51, CD71 <= 25566.07, CD184 <= 9930.06, CD24 <= 83720.23, AQP4 <= 39820.36"
[1] "Astro-Glast+"
           
            Astro-Glast+ Others
  Gated-in           345     63
  Gated-out           55   3537
[1] "GLAST >= 3214.12, CD15 <= 22426.07, CD71 <= 13412.42, CD56 <= 31883.42, CD184 >= -3290.89, CD133 <= 21470.64, CD24 <= 57215.61, O4 <= 2218.76, CD184 <= 32144.34, CD29 <= 43743.48, AQP4 <= 69966.97, CD56 >= 7.5, CD71 >= -6646.57, CD44 <= 345007.76"
[1] "Endothelial"
           
            Endothelial Others
  Gated-in          365     36
  Gated-out          35   3564
[1] "CD71 >= 10724.38, CD15 <= 59777.53, HepaCAM >= -1384.49, CD56 <= 28785.13, CD44 <= 183944, AQP4 <= 89341.93, CD184 <= 22086.07, CD184 >= -13751.17, CD133 <= 13757.14, CD29 >= 953.64, CD133 >= -5808.62, GLAST <= 49558.85, O4 <= 15918.13"
[1] "Neurons-CD56+"
           
            Neurons-CD56+ Others
  Gated-in            284     36
  Gated-out           116   3564
[1] "CD56 >= 19761.3, O4 <= 9958.31, CD15 <= 63114, CD184 <= 10972.48, CD184 >= -8559.27, GLAST <= 24606.12, CD71 <= 42238.55, CD44 <= 184574.3, CD24 <= 106982.1, CD133 <= 32481.14, HepaCAM >= -1472.53, AQP4 <= 88789.06"
[1] "Neurons-CD24+CD56+"
           
            Neurons-CD24+CD56+ Others
  Gated-in                 355     41
  Gated-out                 45   3559
[1] "CD15 >= 18099.18, CD56 <= 73917.76, O4 <= 3294.99, AQP4 <= 72815.42, CD184 >= -4190.68, GLAST <= 49070.28, CD71 <= 33853.67, CD184 <= 40435.34, CD24 <= 90332.37, CD133 <= 44494.74, HepaCAM >= -2542.97, O4 >= -12231.43"
[1] "Oligo"
           
            Oligo Others
  Gated-in    400      3
  Gated-out     0   3597
[1] "O4 >= 10859.74, CD71 <= 34267.48, CD140a >= -3648.7"
[1] "Epithelial"
           
            Epithelial Others
  Gated-in         356     10
  Gated-out         44   3590
[1] "CD184 <= -3891.71, O4 <= 5819.9, CD71 <= 47633.15, CD15 <= 26226.74, CD133 <= 24914.78"

# visualize
DimPlot(seu.q)
Rasterizing points since number of points exceeds 100,000.
To disable this behavior set `raster=FALSE`

Try keeping the mix population



Idents(seu.q) <- 'Batch'
seu <- subset(seu.q, idents = c("AIW002_0306","AIW002_0317A", "AIW002_0317B"))


# downsampe to about 2000 cells so that hypergate can run
# there is an option to down sample per identity class

Idents(seu) <- 'labels.groups'
seu.down <- subset(x= seu, downsample = 400)

DimPlot(seu.down)


table(seu.down$labels.groups)

               Mix      Neurons-CD24+        Astro-CD44+          RG-CD184+          RG-CD133+ 
               400                400                400                400                400 
      Astro-Glast+        Endothelial      Neurons-CD56+ Neurons-CD24+CD56+              Oligo 
               400                400                400                400                  8 
        Epithelial 
               135 
# keeping mix in 

# try hypergate again on one group 
input.xm = as.matrix(GetAssayData(seu.down, slot = 'data'))
xm.t <- t(input.xm)
cluster.labels <- as.vector(seu.down$labels.groups)

#try all at once

cell.types <- c("Neurons-CD24+", "Astro-CD44+", "RG-CD184+", "RG-CD133+", "Astro-Glast+","Endothelial","Neurons-CD56+","Neurons-CD24+CD56+","Oligo","Epithelial","Mix")


# clearer output - should try make a summary of the accuray 

for (cell in cell.types) {
  hg_output <- hypergate(xp = xm.t, gate_vector = cluster.labels, level = cell)
  gating_predicted = subset_matrix_hg(hg_output,xm.t)
  conf.table <- table(ifelse(gating_predicted, "Gated-in", "Gated-out"), ifelse(cluster.labels ==  cell, cell, "Others"))
  print(cell)
  print(conf.table)
  print(hgate_rule(hg_output))
}
[1] "Neurons-CD24+"
           
            Neurons-CD24+ Others
  Gated-in            343     37
  Gated-out            57   3306
[1] "CD24 >= 13299.18, CD71 <= 15020.33, GLAST <= 6247.85, CD133 <= 9075.28, CD56 <= 31399.06, CD184 >= -1546.79, CD15 <= 25893.42, CD44 <= 279215.74, HepaCAM >= -1677.41, CD140a <= 456.65, CD29 <= 25418.07, GLAST >= -6297.82, CD184 <= 30881.18, CD56 >= 35.82, CD133 >= -4171.97, CD71 >= -5082.63, AQP4 <= 44884.91"
[1] "Astro-CD44+"
           
            Astro-CD44+ Others
  Gated-in          249     57
  Gated-out         151   3286
[1] "CD44 >= 67231.91, CD24 <= 15019.02, GLAST <= 2950.76, CD133 <= 7876.55, CD15 <= 23409.98, CD184 <= 15830.88, CD71 <= 13573.62, CD56 <= 23862.51, CD184 >= -1888.38, AQP4 <= 40708.91, CD24 >= -9261.84, GLAST >= -2178.31, CD71 >= -4063.16"
[1] "RG-CD184+"
           
            Others RG-CD184+
  Gated-in      73       278
  Gated-out   3270       122
[1] "CD184 >= 6073.9, CD44 <= 126351.5, GLAST <= 3994.58, CD24 <= 16035.55, CD133 <= 8692.97, CD15 <= 18750.23, CD71 <= 14692.06, CD56 <= 21797.38, CD29 <= 20239.1, AQP4 <= 37590.73, HepaCAM <= 4516.48, CD133 >= -4012.55, HepaCAM >= -1953.82"
[1] "RG-CD133+"
           
            Others RG-CD133+
  Gated-in      40       323
  Gated-out   3303        77
[1] "CD133 >= 8627.78, HepaCAM <= 2157.11, CD15 <= 56587.93, CD71 <= 39815.22, CD56 <= 33589.49, GLAST <= 12828.36, CD184 <= 36549.83, CD24 <= 97777.61, CD44 <= 421935.83, HepaCAM >= -2818.49, CD140a <= 1372"
[1] "Astro-Glast+"
           
            Astro-Glast+ Others
  Gated-in           337     39
  Gated-out           63   3304
[1] "GLAST >= 3625.45, CD15 <= 16184.68, CD71 <= 11501.71, CD133 <= 11466.51, CD56 <= 19596.94, CD44 <= 193034.13, CD184 >= -1649.41, CD184 <= 22766.53, CD24 <= 73144.92, O4 >= -1096.3, AQP4 <= 59695.93"
[1] "Endothelial"
           
            Endothelial Others
  Gated-in          354     23
  Gated-out          46   3320
[1] "CD71 >= 11486.95, CD133 <= 18008.6, CD44 <= 187161.1, CD15 <= 15202.57, O4 >= -529.86, GLAST <= 20353.68, CD56 <= 19264.8, CD184 <= 15685.25, CD133 >= -2747.32, CD24 <= 88581.42"
[1] "Neurons-CD56+"
           
            Neurons-CD56+ Others
  Gated-in            321     59
  Gated-out            79   3284
[1] "CD56 >= 8957.62, CD184 <= 8852.42, CD44 <= 86702.53, CD24 <= 26722.11, GLAST <= 4678.76, CD184 >= -3983.86, AQP4 <= 29543.21, CD15 <= 18438.7, CD71 <= 17751.72, CD133 <= 9807.53, CD29 <= 41638.86, CD133 >= -5725.73, GLAST >= -8086.99, HepaCAM >= -1686.16"
[1] "Neurons-CD24+CD56+"
           
            Neurons-CD24+CD56+ Others
  Gated-in                 366     38
  Gated-out                 34   3305
[1] "CD15 >= 15448.83, CD184 <= 21844.01, CD56 <= 49269.52, CD184 >= -4643.18, CD44 <= 586424.5, HepaCAM <= 4546.85, CD133 <= 55018.56, GLAST >= -161.43, CD29 <= 33451.07"
[1] "Oligo"
           
            Oligo Others
  Gated-in      8      0
  Gated-out     0   3735
[1] "O4 >= 28627.18, CD184 <= 35880.61"
[1] "Epithelial"
           
            Epithelial Others
  Gated-in         105      1
  Gated-out         30   3607
[1] "CD184 <= -4039.86, CD133 <= 7185.97, CD15 <= 20078.87"
[1] "Mix"
           
             Mix Others
  Gated-in   327     55
  Gated-out   73   3288
[1] "CD184 <= 5425.46, CD71 <= 9294.58, CD56 <= 7935.53, CD15 <= 9816.53, CD24 <= 11251.01, CD133 <= 5467.01, GLAST <= 2795.06, CD44 <= 54539.26, CD184 >= -3255.68, HepaCAM >= -1369.28, GLAST >= -1354.1, HepaCAM <= 2797.74, CD133 >= -4223.92, AQP4 >= -9847.13, AQP4 <= 35620.79, O4 >= -564.51"

Try with main groups Neurons1, Neurons2, Astro, RG

Repeat with more populations


# try hypergate again on one group 
input.xm = as.matrix(GetAssayData(seu.down, slot = 'data'))
xm.t <- t(input.xm)
cluster.labels <- as.vector(seu.down$cell.types)

#try all at once

cell.types <- c("Neurons1","Neurons2","Neurons3","Astro1","Astro2","Astro3","RG1","RG2","Endothelial","Oligo","Epithelial","Mix")
# 11 possible populations



# clearer output - should try make a summary of the accuray 

for (cell in cell.types) {
  hg_output <- hypergate(xp = xm.t, gate_vector = cluster.labels, level = cell)
  gating_predicted = subset_matrix_hg(hg_output,xm.t)
  conf.table <- table(ifelse(gating_predicted, "Gated-in", "Gated-out"), ifelse(cluster.labels ==  cell, cell, "Others"))
  print(cell)
  print(conf.table)
  print(hgate_rule(hg_output))
}
[1] "Neurons1"
           
            Neurons1 Others
  Gated-in       687    100
  Gated-out      113   8425
[1] "CD24 >= 12014.34, GLAST <= 7453.9, CD71 <= 12564.71, CD15 <= 22761.75, CD56 <= 36564.79, HepaCAM >= -1684.77, CD133 <= 12759.62, CD184 <= 18942.3, CD184 >= -2138.54, CD44 <= 297781.4, CD29 <= 49937.91, GLAST >= -1282.38, AQP4 <= 61073.35, O4 <= 3770.64, AQP4 >= -12431.75, CD71 >= -5985.69"
[1] "Neurons2"
           
            Neurons2 Others
  Gated-in       592     74
  Gated-out      208   8451
[1] "CD56 >= 13318.21, O4 <= 10932.92, CD184 <= 5351.79, CD15 <= 49168.46, CD184 >= -6786.01, CD133 <= 12046.57, GLAST <= 13007.98, CD44 <= 74315.83, CD71 <= 34112.72, CD24 <= 60858.65, AQP4 <= 50959, CD29 <= 92397.27, CD15 >= -7222.9, GLAST >= -12729.57"
[1] "Neurons3"
           
            Neurons3 Others
  Gated-in       700    109
  Gated-out      100   8416
[1] "CD15 >= 20309.73, CD56 <= 74120.32, CD29 <= 26938.11, GLAST <= 58718.23, O4 <= 6609.57, AQP4 <= 129969.5, CD71 <= 32679.15, CD24 <= 67320, HepaCAM >= -2542.97, CD133 <= 57096.16, CD24 >= -9307.03, CD133 >= -4821.08, CD44 <= 384836.99"
[1] "Astro1"
           
            Astro1 Others
  Gated-in     641     97
  Gated-out    159   8428
[1] "CD44 >= 52004.22, CD184 <= 9251.06, CD24 <= 13080.97, CD133 <= 6711.26, CD15 <= 17193.3, CD29 <= 33110.76, GLAST <= 2848.22, CD71 <= 15857.61, CD184 >= -4062.91, CD44 <= 219347.5, CD56 <= 20286.14, AQP4 <= 27096.05, HepaCAM >= -2556.43, O4 <= 2417.98, CD71 >= -5074.63"
[1] "Astro2"
           
            Astro2 Others
  Gated-in     676    157
  Gated-out    124   8368
[1] "GLAST >= 4033.5, CD15 <= 48464.92, CD71 <= 15797.33, CD29 <= 35236.34, CD56 <= 46998.72, AQP4 <= 59695.93, CD184 >= -1807.47, O4 <= 15459.24, CD184 <= 31411.07, CD133 <= 21956.42, HepaCAM >= -1690.14, CD140a >= -3404.48, CD44 <= 235717.5, CD29 >= -375.6, CD24 <= 117672.6, CD15 >= -4058.33, CD71 >= -5651.4"
[1] "Astro3"
           
            Astro3 Others
  Gated-in     407    131
  Gated-out    393   8394
[1] "CD44 >= 146227.15, CD15 <= 69782.85, CD24 <= 30924.01, CD184 <= 29629.62, CD133 <= 23287.65, GLAST <= 8669.22, CD71 <= 36846.73, CD29 >= -689.18, CD15 >= -3247.74, AQP4 >= -14073.6, CD140a <= 2373.41, O4 <= 3402.92, CD24 >= -10546.65"
[1] "RG1"
           
            Others  RG1
  Gated-in     202  497
  Gated-out   8323  303
[1] "CD184 >= 7583.17, CD24 <= 19506.57, GLAST <= 5172.54, CD44 <= 189251.59, CD15 <= 22986.63, CD133 <= 9112.48, CD71 <= 13843.7, AQP4 <= 34895.56, HepaCAM >= -936.43, CD29 <= 52709.4, CD56 <= 61458.28, CD140a >= -1942.95, O4 <= 3452.21, CD140a <= 2849.82"
[1] "RG2"
           
            Others  RG2
  Gated-in      43  663
  Gated-out   8482  137
[1] "CD133 >= 6424.8, O4 <= 19514.81, CD15 <= 27225.74, CD71 <= 13565.01, GLAST <= 9495.54, CD29 <= 24941.7, CD184 <= 11538.86, AQP4 <= 33753.97, CD184 >= -2777.42, CD24 <= 42787.99, CD56 <= 29662.31, CD44 <= 249589.8, HepaCAM >= -1654.3, CD29 >= 207.6, HepaCAM <= 4835.01"
[1] "Endothelial"
           
            Endothelial Others
  Gated-in          721    101
  Gated-out          79   8424
[1] "CD71 >= 10609.24, CD56 <= 32882.35, CD44 <= 161280.51, CD184 >= -11649.16, GLAST <= 21180.63, CD15 <= 30752.77, O4 <= 21532.58, CD133 <= 43370.79, AQP4 <= 120325.42, CD29 <= 76859.94, HepaCAM >= -1710.35, CD184 <= 33308.03, AQP4 >= -15507.5, CD24 <= 176991.1"
[1] "Oligo"
           
            Oligo Others
  Gated-in    800      8
  Gated-out     0   8517
[1] "O4 >= 10859.74, CD24 <= 79343.15, GLAST <= 22891.68"
[1] "Epithelial"
           
            Epithelial Others
  Gated-in         460      7
  Gated-out         65   8793
[1] "CD184 <= -4151.27, O4 <= 5819.9, AQP4 <= 89898.11, CD71 <= 47633.15, CD44 <= 214766.4, CD56 <= 36845.83, CD15 <= 26226.74, CD133 <= 24914.78"
[1] "Mix"
           
             Mix Others
  Gated-in   610    104
  Gated-out  190   8421
[1] "CD56 <= 10211.03, CD184 <= 5139.33, CD133 <= 4707.85, CD44 <= 56043.53, GLAST <= 2098.57, CD24 <= 8364.47, CD184 >= -3392.68, CD71 <= 9031.62, CD15 <= 10275.57, O4 >= -1903.16, O4 <= 4859.84, AQP4 <= 39070.41, CD29 <= 49783.17, AQP4 >= -8978.09, HepaCAM <= 2949.62, CD29 >= -1163.49, CD133 >= -4899.45"

Load in libraries

require("reshape2") #visualization
Loading required package: reshape2
require("flowStats") #Alignment functions
Loading required package: flowStats
require("scales") #scale colour intensity for visualization
Loading required package: scales
require("dplyr")
Loading required package: dplyr
Warning: package ‘dplyr’ was built under R version 4.1.2

Attaching package: ‘dplyr’

The following objects are masked from ‘package:stats’:

    filter, lag

The following objects are masked from ‘package:base’:

    intersect, setdiff, setequal, union
library("hypergate")
library("Seurat")
Warning: package ‘Seurat’ was built under R version 4.1.2
Attaching SeuratObject

Read in the data for gating

seu.r <- readRDS("/Users/rhalenathomas/Documents/Data/FlowCytometry/PhenoID/Analysis/9MBO/prepro_outs/clusters/AllcellLablesMarch25.Rds")
Warning: stack imbalance in '<-', 2 then 4

I”m going to run the hypergates again - maybe multiple times to see how consitatant to output will be



Idents(seu.r) <- 'cell.types'
i = 300
set.seed(i)
seu.down <- subset(x= seu.r, downsample = 200)


# try hypergate again on one group 
input.xm = as.matrix(GetAssayData(seu.down, slot = 'data'))
xm.t <- t(input.xm)
cluster.labels <- as.vector(seu.down$cell.types)

#try all at once

cell.types <- c("Neurons1","Neurons2","Neurons3","Astro1","Astro2","Astro3","RG1","RG2","Endothelial","Oligo","Epithelial","Mix")
# 11 possible populations



# clearer output - should try make a summary of the accuray 

for (cell in cell.types) {
  hg_output <- hypergate(xp = xm.t, gate_vector = cluster.labels, level = cell)
  gating_predicted = subset_matrix_hg(hg_output,xm.t)
  conf.table <- table(ifelse(gating_predicted, "Gated-in", "Gated-out"), ifelse(cluster.labels ==  cell, cell, "Others"))
  print(cell)
  print(conf.table)
  print(hgate_rule(hg_output))
}
[1] "Neurons1"
           
            Neurons1 Others
  Gated-in       177     10
  Gated-out       23   2190
[1] "CD24 >= 13768.18, GLAST <= 6532.14, CD71 <= 14511.02, CD15 <= 29892.06, CD133 <= 10724.63, CD56 <= 36819.98, HepaCAM >= -1296.45, CD184 >= -4583.34, CD29 <= 33528.68, CD184 <= 26416.42, CD44 <= 235085.5, GLAST >= -696.95, AQP4 <= 43922.06"
[1] "Neurons2"
           
            Neurons2 Others
  Gated-in       164      9
  Gated-out       36   2191
[1] "CD56 >= 11467.62, O4 <= 4980.29, CD15 <= 27532.65, CD184 >= -4246.8, CD140a >= -2207.93, CD184 <= 4810.4, CD133 <= 11653.95, CD44 <= 94883.57, GLAST <= 10573.34, CD71 <= 81257.09, CD24 <= 79820.24, CD133 >= -4507.04, HepaCAM <= 4810.69"
[1] "Neurons3"
           
            Neurons3 Others
  Gated-in       174     14
  Gated-out       26   2186
[1] "CD15 >= 20912.51, GLAST <= 27110.83, HepaCAM <= 3711.66, CD56 <= 81379.32, CD133 >= -2782.85, CD24 <= 91855.94, CD140a <= 1395.53, O4 <= 6609.57"
[1] "Astro1"
           
            Astro1 Others
  Gated-in     162     12
  Gated-out     38   2188
[1] "CD44 >= 56591.37, CD133 <= 5938.13, CD184 <= 11559.47, CD24 <= 12227.97, CD29 <= 21481.8, CD15 <= 11202.52, CD184 >= -2372.25, CD71 <= 12071.88, GLAST <= 4158.8, CD44 <= 208706.6, HepaCAM >= -1164.12, AQP4 <= 23637.02, CD56 <= 17624.81"
[1] "Astro2"
           
            Astro2 Others
  Gated-in     169     21
  Gated-out     31   2179
[1] "GLAST >= 3637.79, CD15 <= 18398.54, CD29 <= 25116.69, CD71 <= 17606.01, CD56 <= 29675.18, CD24 <= 45161.19, CD184 <= 28293.85, CD184 >= -1759.5, O4 <= 3344.42, CD133 <= 23488.65, HepaCAM >= -1260.12, AQP4 <= 65021.79"
[1] "Astro3"
           
            Astro3 Others
  Gated-in      92     22
  Gated-out    108   2178
[1] "CD44 >= 147465.5, CD24 <= 16082.73, CD15 <= 26416.42, CD24 >= -3042.91, CD184 <= 42234.54, CD133 <= 15396.03, CD71 <= 16901.3, CD29 >= -405.62, CD71 >= -5047.31, O4 <= 4040.76"
[1] "RG1"
           
            Others  RG1
  Gated-in      38  122
  Gated-out   2162   78
[1] "CD184 >= 6652.03, CD24 <= 8437.13, CD133 <= 9089.13, CD15 <= 9000.35, GLAST <= 6168.13, HepaCAM >= -650.54, AQP4 <= 25403.45, CD29 <= 27345.65, CD71 <= 14089.39, CD44 <= 337212.4, CD56 <= 29969.06, CD140a >= -2399.99"
[1] "RG2"
           
            Others  RG2
  Gated-in       8  180
  Gated-out   2192   20
[1] "CD133 >= 7355.82, CD29 <= 21800.4, GLAST <= 5038.9, O4 <= 3086.43, CD15 <= 14869.81, CD71 <= 23635.28, CD184 >= -3013.57, AQP4 <= 54441.39, CD140a <= 977.9, CD184 <= 24178.96, CD44 <= 214500.5"
[1] "Endothelial"
           
            Endothelial Others
  Gated-in          182     22
  Gated-out          18   2178
[1] "CD71 >= 11682.33, O4 <= 2614.47, CD15 <= 21782.44, CD184 <= 15065.71, CD184 >= -8125.55, GLAST <= 17202.79, AQP4 <= 149799.8, CD24 >= -8685.52, CD133 >= -3085.96"
[1] "Oligo"
           
            Oligo Others
  Gated-in    200      0
  Gated-out     0   2200
[1] "O4 >= 10768.08, CD71 <= 30969.27, AQP4 <= 232540.9"
[1] "Epithelial"
           
            Epithelial Others
  Gated-in         176      0
  Gated-out         24   2200
[1] "CD184 <= -4593.41, O4 <= 5819.9, CD29 <= 67460.48, CD71 <= 45227.99"
[1] "Mix"
           
             Mix Others
  Gated-in   162     19
  Gated-out   38   2181
[1] "CD56 <= 9565.82, CD44 <= 56043.53, GLAST <= 1838.73, CD133 <= 5840.58, CD184 >= -3392.68, CD184 <= 4747.07, CD24 <= 10921.39, CD71 <= 8865.49, CD15 <= 10275.57, O4 >= -1903.16, CD29 <= 42997.34, O4 <= 4859.84, AQP4 <= 32325, HepaCAM <= 2446.18, CD140a <= 1378.82, CD29 >= -259.6"

Try using the smaller labeled object - will still need to subset Also make groupings of cells


seu <- readRDS("/Users/rhalenathomas/Documents/Data/FlowCytometry/PhenoID/Analysis/9MBO/prepro_outsjan20-9000cells/Figure3/Louvkn60DifferentCellLabels220220318.Rds")

AB <- c("CD24","CD56","CD29","CD15","CD184","CD133","CD71","CD44","GLAST","AQP4","HepaCAM", "CD140a","O4")

#DimPlot(seu)
#DoHeatmap(seu, features = AB)

Run with different cutoff of cells in down sampling


unique(seu$labels6)
 [1] Neurons-Mix  Astro-2      RG-2         Astro-1      Neurons      Mix          NPC          RG-1        
 [9] RG-3         Endothelial  Oligo        EarlyNeurons Epithelial   OPC         
14 Levels: Mix RG-1 Neurons-Mix Neurons NPC Astro-1 Astro-2 RG-2 EarlyNeurons RG-3 Endothelial Oligo ... Epithelial

Relabel cell type groups

for (cell in cell.types) {
  hg_output <- hypergate(xp = xm.t, gate_vector = cluster.labels, level = cell)
  gating_predicted = subset_matrix_hg(hg_output,xm.t)
  conf.table <- table(ifelse(gating_predicted, "Gated-in", "Gated-out"), ifelse(cluster.labels ==  cell, cell, "Others"))
  print(cell)
  print(conf.table)
  print(hgate_rule(hg_output))
  # visualize the predicted cells 
  predicted.cell.type = paste(cell,"gated",sep=".")
  seu.down <- AddMetaData(object=seu.down, metadata=gating_predicted, col.name = predicted.cell.type )
  print(DimPlot(seu.down, group.by = predicted.cell.type, split.by = 'gating.main'))
  
  
  
}
[1] "glia"
           
            glia Others
  Gated-in   278    116
  Gated-out  222   2884
[1] "CD184 >= 4048.93, CD44 <= 81024.25, CD133 <= 8220.56, CD24 <= 13471.48, CD15 <= 21063.09, CD56 <= 25971.81, O4 >= -496.34, CD15 >= -4296.1, CD29 <= 77817.9, CD44 >= -23.89"
[1] "RG2"
           
            Others  RG2
  Gated-in      43  467
  Gated-out   2957   33
[1] "CD133 >= 6734, CD15 <= 23722, CD24 <= 31379.93, CD56 <= 38834.67, CD71 <= 28283.44, CD44 <= 322230.73, CD184 <= 35943.31, GLAST <= 13336.77, CD29 >= -410.35, HepaCAM >= -1703.95, CD56 >= 242.82, CD140a >= -4185.26"
[1] "Neurons1"
           
            Neurons1 Others
  Gated-in       414     66
  Gated-out       86   2934
[1] "CD56 >= 12342.8, CD184 <= 7771.36, CD15 <= 30861.38, CD133 <= 11000.77, CD44 <= 94073.69, O4 <= 11278.24, CD29 >= -235125.35, CD24 <= 99632.47, HepaCAM <= 2868.25, CD184 >= -5162.05, CD71 <= 42344.32, GLAST <= 20894.66"
[1] "Neurons2"
           
            Neurons2 Others
  Gated-in       452     47
  Gated-out       48   2953
[1] "CD24 >= 10365.89, CD56 <= 34448.68, CD15 <= 23516.48, CD133 <= 22687.34, CD44 <= 338951.58, CD71 <= 18026.04, CD184 <= 27749.83, CD140a <= 886.33, CD44 >= -183.98, HepaCAM <= 4544.73, GLAST <= 5705.44"
[1] "Neurons3"
           
            Neurons3 Others
  Gated-in       452     59
  Gated-out       48   2941
[1] "CD15 >= 18346.88, CD56 <= 116929.7, AQP4 <= 59436.34, CD24 <= 152360.23, CD133 <= 46426.43, CD71 <= 20689.09, O4 <= 4375.6, HepaCAM >= -1869.01"
[1] "Astro"
           
            Astro Others
  Gated-in    451     62
  Gated-out    49   2938
[1] "CD44 >= 81568.02, CD24 <= 13706.44, CD15 <= 23786.78, CD133 <= 8845.81, CD56 <= 24286.68, CD184 <= 20615.25, GLAST <= 6491.94, AQP4 <= 48746.29, CD71 <= 19185.12, CD184 >= -5120.87, HepaCAM >= -2920.13"

The glia is only 50/50 and no good The other cell type accuracy is high

Try plotting the results to see where the labelled cells end up

Instead of subsampling in advance I can sample using hgate_sample to also sample negative events. This just gives you an idea of how many cells you need to sample


input.xm = as.matrix(GetAssayData(seu, slot = 'data'))
xm.t <- t(input.xm)
cluster.labels <- as.vector(seu$gating.main)

# hypergate( xp = matrix, gate_vector = labels, level = thing to gate)
sample = hgate_sample(gate_vector = cluster.labels, level = "Astro1", size=1000)


tab = table(ifelse(sample, "In", "Out"), ifelse(cluster.labels == "Astro1", "Positive pop.", "Negative pop."))
tab[1, ]/colSums(tab)  ## Fraction of subsampled events for positive and negative populations
Negative pop. Positive pop. 
    0.1299577     0.1299545 
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKCgpgYGB7cn0KI2luc3RhbGwgCgojIGRlcGVuZGVuY2llcwppbnN0YWxsLnBhY2thZ2VzKGMoInNwIiwgInBvbHljbGlwIiwgInJnZW9zIikpCgoKCiMgcGFja2FnZSBmcm9tIGdpdGh1YgoKbGlicmFyeShkZXZ0b29scykKaW5zdGFsbF9naXRodWIocmVwbyA9ICJlYmVjaHQvaHlwZXJnYXRlIikKCgpsaWJyYXJ5KCJTZXVyYXQiKQpsaWJyYXJ5KCJnZ3Bsb3QyIikKbGlicmFyeSgiZHBseXIiKQoKCmBgYAoKSHlwZXJnYXRlIHRha2VzIGluIAoxLiBhbiBleHByZXNzaW9uIG1hdHJpeAoyLiBhIHZlY3RvciBvZiBldmVudHMgdG8gYXR0ZW1wdCB0byBnYXRlIG9uIC0gdGhlcmUgYXJlIGRpZmZlcmVudCB3YXlzIHRvIGdldCB0aGVzZQoKaW50ZXJhY3RpdmUgZ2F0aW5nIC0gdHJ5IGxhdGVyCkNsdXN0ZXJpbmcgLSB0aGlzIGlzIHdoYXQgSSB3YW50IHRvIHVzZQoKaHlwZXJnYXRlIGlzIHRoZSBmdW5jdGlvbiB0byBvcHRvbWl6ZSBnYXRpbmcgc3RyYXRlZ2llcwoKeHAgPSBhIG51bWJlcmljIG1hdHJpeCBlbmNvZGluZyBleHByZXNzaW9uIApnYXRlX3ZlY3RvciBhIHZlY3RvciB3aXRoIGEgZmV3IHVuaXF1ZSB2YWx1ZXMgLS0tIHRoaXMgc2hvdWxkIGJlIHRoZSBjbHVzdGVyIGxhYmVscwpsZXZlbCBzcGVjaWZpZXMgd2hhdCB2YWx1ZSBvZiBnYXRlIHZlY3RvciB0b2dhdGUgdXBvbiAKCmBgYHtyfQpsaWJyYXJ5KCJoeXBlcmdhdGUiKQoKaW5wdXQueG0gPSBhcy5tYXRyaXgoR2V0QXNzYXlEYXRhKHNldS5xLCBzbG90ID0gJ3NjYWxlLmRhdGEnKSkKeG0udCA8LSB0KGlucHV0LnhtKQpjbHVzdGVyLmxhYmVscyA8LSBhcy52ZWN0b3Ioc2V1LnEkbGFiZWxzKQoKCmhnX291dHB1dCA8LSBoeXBlcmdhdGUoeHAgPSB4bS50LCBnYXRlX3ZlY3RvciA9IGNsdXN0ZXIubGFiZWxzLCBsZXZlbCA9ICdBc3RybzEnKQoKIyB3cml0aW5nIGxldmVsID0gMSByZXN1bHRlZCBlbXB0eSBvdXRwdXQKIyBwdXR0aW5nICdBc3RybzEnIGlzIHJ1bm5pbmcgYnV0IHRha2luZyBhIHZlcnkgbG9uZyB0aW1lCiMgSSBiZWxpZXZlIEkgd2lsbCBoYXZlIHRvIGRvd24gc2FtcGxlIHRoZSBTZXVyYXQgb2JqZWN0LiAgSSB0aGluZyBJIG1pZ2h0IHdhbnQgdG8gc3Vic2V0IHRoZSBBSVcwMDIgZmlyc3QKCgoKCmBgYAoKCkknbGwgbmVlZCB0byBkb3duc2FtcGxlIHRoZSBzZXVyYXQgb2JqZWN0CgpgYGB7cn0KSWRlbnRzKHNldS5xKSA8LSAnQmF0Y2gnCgp1bmlxdWUoc2V1JEJhdGNoKQojIHN1YnNldCB0aGUgQUlXIGJlY2F1c2Ugd2Ugd2lsbCB1c2UgQUlXIGluIHRoZSBGQUNTIGV4cGVyaW1lbnQKCnNldSA8LSBzdWJzZXQoc2V1LnEsIGlkZW50cyA9IGMoIkFJVzAwMl8wMzA2IiwiQUlXMDAyXzAzMTdBIiwgIkFJVzAwMl8wMzE3QiIpKQoKIyBkb3duc2FtcGUgdG8gYWJvdXQgMjAwMCBjZWxscyBzbyB0aGF0IGh5cGVyZ2F0ZSBjYW4gcnVuCiMgdGhlcmUgaXMgYW4gb3B0aW9uIHRvIGRvd24gc2FtcGxlIHBlciBpZGVudGl0eSBjbGFzcwoKSWRlbnRzKHNldSkgPC0gJ2xhYmVscycKc2V1LmRvd24gPC0gc3Vic2V0KHg9IHNldSwgZG93bnNhbXBsZSA9IDIwMCkKCkRpbVBsb3Qoc2V1LmRvd24pCgoKCgpgYGAKCmBgYHtyfQojIHRyeSBoeXBlcmdhdGUgYWdhaW4gb24gb25lIGdyb3VwIAppbnB1dC54bSA9IGFzLm1hdHJpeChHZXRBc3NheURhdGEoc2V1LmRvd24sIHNsb3QgPSAnc2NhbGUuZGF0YScpKQp4bS50IDwtIHQoaW5wdXQueG0pCmNsdXN0ZXIubGFiZWxzIDwtIGFzLnZlY3RvcihzZXUuZG93biRsYWJlbHMpCgoKaGdfb3V0cHV0IDwtIGh5cGVyZ2F0ZSh4cCA9IHhtLnQsIGdhdGVfdmVjdG9yID0gY2x1c3Rlci5sYWJlbHMsIGxldmVsID0gJ0FzdHJvMScpCgoKCmBgYAoKCgoKCgpUcnkgY2hlY2tpbmcgdGhlIHJlc3VsdHMKCmBgYHtyfQoKZ2F0aW5nX3ByZWRpY3RlZCA9IHN1YnNldF9tYXRyaXhfaGcoaGdfb3V0cHV0LHhtLnQpCgoKdGFibGUoaWZlbHNlKGdhdGluZ19wcmVkaWN0ZWQsICJHYXRlZC1pbiIsICJHYXRlZC1vdXQiKSwgaWZlbHNlKGNsdXN0ZXIubGFiZWxzID09IAogICAgJ0FzdHJvMScsICJFdmVudHMgb2YgaW50ZXJlc3QiLCAiT3RoZXJzIikpCgojIGFzIHdlIHN0YXJ0ZWQgd2l0aCAyMDAgYXN0cm8xIHdlIGNhcHR1cmVkIGEgZ29vZCBhbW91bnQKCgpgYGAKCk5vdyB3ZSBjYW4gc2VlIGlmIGVhY2ggY2VsbCBwYXN0IHBhcmFtZXRlcnMgZm9yIHRoZSB0aHJlc2hvbGQgZm9yIGVhY2ggQUIKCmBgYHtyfQoKYm0gPSBib29sbWF0KGdhdGUgPSBoZ19vdXRwdXQsIHhwID0geG0udCkKaGVhZChibSkKCgoKYGBgCgpQbG90cyBzb21lIGdhdGVzCgoKYGBge3J9CgpwbG90X2dhdGluZ19zdHJhdGVneShnYXRlID0gaGdfb3V0cHV0LCB4cCA9IHhtLnQsIGdhdGVfdmVjdG9yID0gY2x1c3Rlci5sYWJlbHMsIAogICAgbGV2ZWwgPSAnQXN0cm8xJywgaGlnaGxpZ2h0ID0gImZpcmVicmljazMiKQoKYGBgCgpDaGFubmVsIGNvbnRyaWJ1dGlvbnMKCmBgYHtyfQoKY29udHJpYnV0aW9ucyA9IGNoYW5uZWxzX2NvbnRyaWJ1dGlvbnMoZ2F0ZSA9IGhnX291dHB1dCwgeHAgPSB4bS50LCBnYXRlX3ZlY3RvciA9IGNsdXN0ZXIubGFiZWxzLCAKICAgIGxldmVsID0gJ0FzdHJvMScsIGJldGEgPSAxKQpiYXJwbG90KGNvbnRyaWJ1dGlvbnMsIGhvcml6ID0gVFJVRSwgCiAgICB4bGFiID0gIkYxLXNjb3JlIGRldGVyaW9yYXRpb24gd2hlbiB0aGUgcGFyYW1ldGVyIGlzIGlnbm9yZWQiKQpwcmludChjb250cmlidXRpb25zKQoKYGBgCgpXZSBjb3VsZCByZW9wdGltaXplIHVzaW5nIG9ubHkgdGhlIHRvcCA0IApCdXQgcmlnaHQgbm93IEknbGwgbGVhdmUgdGhpcwoKCmBgYHtyfQpoZ2F0ZV9waGVubyhoZ19vdXRwdXQpCgpgYGAKCmBgYHtyfQpoZ2F0ZV9ydWxlKGhnX291dHB1dCkKYGBgCgpgYGB7cn0KaGdhdGVfaW5mbyhoZ19vdXRwdXQpICAjIG1ha2UgYSBoZWxwZnVsIHRhYmxlIApgYGAKCkkgbmVlZCB0byBkZWZpbmUgdGhlIGdyb3VwcyBJIHdhbnQgdG8gZ2F0ZSBmaXJzdCBhbmQgdGhlbiB1c2UgdGhpcyB0byBnYXRlIHRoZW0uIAoKYGBge3J9CkFCLm9yZGVyIDwtIGMoIkNEMjQiLCJDRDU2IiwiQ0QyOSIsIkNEMTUiLCJDRDE4NCIsIkNEMTMzIiwiQ0Q3MSIsIkNENDQiLCJHTEFTVCIsIkFRUDQiLCJIZXBhQ0FNIiwgIkNEMTQwYSIsIk80IikKCgpSaWRnZVBsb3Qoc2V1LmRvd24sIGZlYXR1cmVzID0gIkNENDQiLCBsb2cgPSBUUlVFICkKUmlkZ2VQbG90KHNldS5kb3duLCBmZWF0dXJlcyA9ICJDRDI0IiwgbG9nID0gVFJVRSApCgoKYGBgCgpSZWdyb3VwIHRoZSBzaW1pbGFyIGZvciBnYXRpbmcgYW5kIHJlbW92ZSBtaXggY2VsbHMgdGhhdCBtaWdodCBjb25mdXNlCgpgYGB7cn0KCgpJZGVudHMoc2V1LnEpIDwtICdsYWJlbHMuZ3JvdXBzJwpzZXUgPC0gc3Vic2V0KHg9IHNldS5xLCBpZGVudHMgPSBjKCJOZXVyb25zLUNEMjQrIiwiQXN0cm8tQ0Q0NCsiLCJSRy1DRDE4NCsiLCJSRy1DRDEzMysiLCJBc3Ryby1HbGFzdCsiLCJBc3Ryby1DRDQ0KyIsIlJHLUNEMTg0KyIsIkFzdHJvLUNENDQrIiwiRW5kb3RoZWxpYWwiLCJBc3Ryby1DRDQ0KyIsIk5ldXJvbnMtQ0Q1NisiLCJOZXVyb25zLUNEMjQrQ0Q1NisiLCJOZXVyb25zLUNENTYrIiwiQXN0cm8tQ0Q0NCsiLCJOZXVyb25zLUNENTYrIiwiTmV1cm9ucy1DRDI0KyIsIlJHLUNEMTMzKyIsIk9saWdvIiwiRXBpdGhlbGlhbCIsIk5ldXJvbnMtQ0QyNCtDRDU2KyIpKSAKCkRpbVBsb3Qoc2V1LCBsYWJlbCA9IFRSVUUsIHJlcGVsID0gVFJVRSkKCklkZW50cyhzZXUpIDwtICdCYXRjaCcKc2V1IDwtIHN1YnNldChzZXUucSwgaWRlbnRzID0gYygiQUlXMDAyXzAzMDYiLCJBSVcwMDJfMDMxN0EiLCAiQUlXMDAyXzAzMTdCIikpCgoKIyBkb3duc2FtcGUgdG8gYWJvdXQgMjAwMCBjZWxscyBzbyB0aGF0IGh5cGVyZ2F0ZSBjYW4gcnVuCiMgdGhlcmUgaXMgYW4gb3B0aW9uIHRvIGRvd24gc2FtcGxlIHBlciBpZGVudGl0eSBjbGFzcwoKSWRlbnRzKHNldSkgPC0gJ2xhYmVscy5ncm91cHMnCnNldS5kb3duIDwtIHN1YnNldCh4PSBzZXUsIGRvd25zYW1wbGUgPSA0MDApCgpEaW1QbG90KHNldS5kb3duKQoKdGFibGUoc2V1LmRvd24kbGFiZWxzLmdyb3VwcykKCgoKCmBgYApIeXBlcmdhdGUgb24gb25lIGdyb3VwCgpgYGB7cn0KIyB0cnkgaHlwZXJnYXRlIGFnYWluIG9uIG9uZSBncm91cCAKaW5wdXQueG0gPSBhcy5tYXRyaXgoR2V0QXNzYXlEYXRhKHNldS5kb3duLCBzbG90ID0gJ3NjYWxlLmRhdGEnKSkKeG0udCA8LSB0KGlucHV0LnhtKQpjbHVzdGVyLmxhYmVscyA8LSBhcy52ZWN0b3Ioc2V1LmRvd24kbGFiZWxzLmdyb3VwcykKCiN0cnkgYWxsIGF0IG9uY2UKCmNlbGwudHlwZXMgPC0gYygiTmV1cm9ucy1DRDI0KyIsICJBc3Ryby1DRDQ0KyIsICJSRy1DRDE4NCsiLCAiUkctQ0QxMzMrIiwgIkFzdHJvLUdsYXN0KyIsIkVuZG90aGVsaWFsIiwiTmV1cm9ucy1DRDU2KyIsIk5ldXJvbnMtQ0QyNCtDRDU2KyIsIk9saWdvIiwiRXBpdGhlbGlhbCIpCgpmb3IgKGNlbGwgaW4gY2VsbC50eXBlcykgewogIGhnX291dHB1dCA8LSBoeXBlcmdhdGUoeHAgPSB4bS50LCBnYXRlX3ZlY3RvciA9IGNsdXN0ZXIubGFiZWxzLCBsZXZlbCA9IGNlbGwpCiAgZ2F0aW5nX3ByZWRpY3RlZCA9IHN1YnNldF9tYXRyaXhfaGcoaGdfb3V0cHV0LHhtLnQpCiAgY29uZi50YWJsZSA8LSB0YWJsZShpZmVsc2UoZ2F0aW5nX3ByZWRpY3RlZCwgIkdhdGVkLWluIiwgIkdhdGVkLW91dCIpLCBpZmVsc2UoY2x1c3Rlci5sYWJlbHMgPT0gIGNlbGwsIGNlbGwsICJPdGhlcnMiKSkKICBwcmludChjZWxsKQogIHByaW50KGNvbmYudGFibGUpCiAgcGxvdF9nYXRpbmdfc3RyYXRlZ3koZ2F0ZSA9IGhnX291dHB1dCwgeHAgPSB4bS50LCBnYXRlX3ZlY3RvciA9IGNsdXN0ZXIubGFiZWxzLCAKICAgIGxldmVsID0gY2VsbCwgaGlnaGxpZ2h0ID0gImZpcmVicmljazMiKQogIGdhdGUudGFibGUgPC0gaGdhdGVfaW5mbyhoZ19vdXRwdXQpIAogIHByaW50KGdhdGUudGFibGUpCn0KCgojIHRoaXMgcHJpbnRzIHRoZSB0aHJlc2hvbGQgZm9yIGVhY2ggZ2F0ZQpoZ2F0ZV9ydWxlKGhnX291dHB1dCkKCiMgY2xlYXJlciBvdXRwdXQgLSBzaG91bGQgdHJ5IG1ha2UgYSBzdW1tYXJ5IG9mIHRoZSBhY2N1cmF5IAoKZm9yIChjZWxsIGluIGNlbGwudHlwZXMpIHsKICBoZ19vdXRwdXQgPC0gaHlwZXJnYXRlKHhwID0geG0udCwgZ2F0ZV92ZWN0b3IgPSBjbHVzdGVyLmxhYmVscywgbGV2ZWwgPSBjZWxsKQogIGdhdGluZ19wcmVkaWN0ZWQgPSBzdWJzZXRfbWF0cml4X2hnKGhnX291dHB1dCx4bS50KQogIGNvbmYudGFibGUgPC0gdGFibGUoaWZlbHNlKGdhdGluZ19wcmVkaWN0ZWQsICJHYXRlZC1pbiIsICJHYXRlZC1vdXQiKSwgaWZlbHNlKGNsdXN0ZXIubGFiZWxzID09ICBjZWxsLCBjZWxsLCAiT3RoZXJzIikpCiAgcHJpbnQoY2VsbCkKICBwcmludChjb25mLnRhYmxlKQogIHByaW50KGhnYXRlX3J1bGUoaGdfb3V0cHV0KSkKfQoKCgoKCgpgYGAKCkNoZWNrIHJlc3VsdHMKCmBgYHtyfQpnYXRpbmdfcHJlZGljdGVkID0gc3Vic2V0X21hdHJpeF9oZyhoZ19vdXRwdXQseG0udCkKCgp0YWJsZShpZmVsc2UoZ2F0aW5nX3ByZWRpY3RlZCwgIkdhdGVkLWluIiwgIkdhdGVkLW91dCIpLCBpZmVsc2UoY2x1c3Rlci5sYWJlbHMgPT0gCiAgICAnQXN0cm8tQ0Q0NCsnLCAiRXZlbnRzIG9mIGludGVyZXN0IiwgIk90aGVycyIpKQoKI25vdCBncmVhdCBhY2N1cmFjeQoKYm0gPSBib29sbWF0KGdhdGUgPSBoZ19vdXRwdXQsIHhwID0geG0udCkKaGVhZChibSkKCnBsb3RfZ2F0aW5nX3N0cmF0ZWd5KGdhdGUgPSBoZ19vdXRwdXQsIHhwID0geG0udCwgZ2F0ZV92ZWN0b3IgPSBjbHVzdGVyLmxhYmVscywgCiAgICBsZXZlbCA9ICdBc3Ryby1DRDQ0KycsIGhpZ2hsaWdodCA9ICJmaXJlYnJpY2szIikKCmNvbnRyaWJ1dGlvbnMgPSBjaGFubmVsc19jb250cmlidXRpb25zKGdhdGUgPSBoZ19vdXRwdXQsIHhwID0geG0udCwgZ2F0ZV92ZWN0b3IgPSBjbHVzdGVyLmxhYmVscywgCiAgICBsZXZlbCA9ICdBc3Ryby1DRDQ0KycsIGJldGEgPSAxKQpiYXJwbG90KGNvbnRyaWJ1dGlvbnMsIGhvcml6ID0gVFJVRSwgCiAgICB4bGFiID0gIkYxLXNjb3JlIGRldGVyaW9yYXRpb24gd2hlbiB0aGUgcGFyYW1ldGVyIGlzIGlnbm9yZWQiKQpwcmludChjb250cmlidXRpb25zKQoKaGdhdGVfcGhlbm8oaGdfb3V0cHV0KQoKaGdhdGVfcnVsZShoZ19vdXRwdXQpCgpnYXRlLnRhYmxlIDwtIGhnYXRlX2luZm8oaGdfb3V0cHV0KSAgIyBtYWtlIGEgaGVscGZ1bCB0YWJsZSAKCgpgYGAKCgoKVHJ5IHdpdGggdGhlIGlucHV0IGRhdGEKYGBge3J9CiMgdHJ5IGh5cGVyZ2F0ZSBhZ2FpbiBvbiBvbmUgZ3JvdXAgCmlucHV0LnhtID0gYXMubWF0cml4KEdldEFzc2F5RGF0YShzZXUuZG93biwgc2xvdCA9ICdkYXRhJykpCnhtLnQgPC0gdChpbnB1dC54bSkKY2x1c3Rlci5sYWJlbHMgPC0gYXMudmVjdG9yKHNldS5kb3duJGxhYmVscy5ncm91cHMpCgojdHJ5IGFsbCBhdCBvbmNlCgpjZWxsLnR5cGVzIDwtIGMoIk5ldXJvbnMtQ0QyNCsiLCAiQXN0cm8tQ0Q0NCsiLCAiUkctQ0QxODQrIiwgIlJHLUNEMTMzKyIsICJBc3Ryby1HbGFzdCsiLCJFbmRvdGhlbGlhbCIsIk5ldXJvbnMtQ0Q1NisiLCJOZXVyb25zLUNEMjQrQ0Q1NisiLCJPbGlnbyIsIkVwaXRoZWxpYWwiKQoKCiMgY2xlYXJlciBvdXRwdXQgLSBzaG91bGQgdHJ5IG1ha2UgYSBzdW1tYXJ5IG9mIHRoZSBhY2N1cmF5IAoKZm9yIChjZWxsIGluIGNlbGwudHlwZXMpIHsKICBoZ19vdXRwdXQgPC0gaHlwZXJnYXRlKHhwID0geG0udCwgZ2F0ZV92ZWN0b3IgPSBjbHVzdGVyLmxhYmVscywgbGV2ZWwgPSBjZWxsKQogIGdhdGluZ19wcmVkaWN0ZWQgPSBzdWJzZXRfbWF0cml4X2hnKGhnX291dHB1dCx4bS50KQogIGNvbmYudGFibGUgPC0gdGFibGUoaWZlbHNlKGdhdGluZ19wcmVkaWN0ZWQsICJHYXRlZC1pbiIsICJHYXRlZC1vdXQiKSwgaWZlbHNlKGNsdXN0ZXIubGFiZWxzID09ICBjZWxsLCBjZWxsLCAiT3RoZXJzIikpCiAgcHJpbnQoY2VsbCkKICBwcmludChjb25mLnRhYmxlKQogIHByaW50KGhnYXRlX3J1bGUoaGdfb3V0cHV0KSkKICAjIHNhdmUgZmlsZXMgd2l0aCB0aGUgcGxvdHMgCn0KCgoKYGBgCgpgYGB7cn0KCiMgdmlzdWFsaXplCkRpbVBsb3Qoc2V1LnEpCgpgYGAKVHJ5IGtlZXBpbmcgdGhlIG1peCBwb3B1bGF0aW9uCgpgYGB7cn0KCgpJZGVudHMoc2V1LnEpIDwtICdCYXRjaCcKc2V1IDwtIHN1YnNldChzZXUucSwgaWRlbnRzID0gYygiQUlXMDAyXzAzMDYiLCJBSVcwMDJfMDMxN0EiLCAiQUlXMDAyXzAzMTdCIikpCgoKIyBkb3duc2FtcGUgdG8gYWJvdXQgMjAwMCBjZWxscyBzbyB0aGF0IGh5cGVyZ2F0ZSBjYW4gcnVuCiMgdGhlcmUgaXMgYW4gb3B0aW9uIHRvIGRvd24gc2FtcGxlIHBlciBpZGVudGl0eSBjbGFzcwoKSWRlbnRzKHNldSkgPC0gJ2xhYmVscy5ncm91cHMnCnNldS5kb3duIDwtIHN1YnNldCh4PSBzZXUsIGRvd25zYW1wbGUgPSA0MDApCgpEaW1QbG90KHNldS5kb3duKQoKdGFibGUoc2V1LmRvd24kbGFiZWxzLmdyb3VwcykKCgpgYGAKCgpgYGB7cn0KIyBrZWVwaW5nIG1peCBpbiAKCiMgdHJ5IGh5cGVyZ2F0ZSBhZ2FpbiBvbiBvbmUgZ3JvdXAgCmlucHV0LnhtID0gYXMubWF0cml4KEdldEFzc2F5RGF0YShzZXUuZG93biwgc2xvdCA9ICdkYXRhJykpCnhtLnQgPC0gdChpbnB1dC54bSkKY2x1c3Rlci5sYWJlbHMgPC0gYXMudmVjdG9yKHNldS5kb3duJGxhYmVscy5ncm91cHMpCgojdHJ5IGFsbCBhdCBvbmNlCgpjZWxsLnR5cGVzIDwtIGMoIk5ldXJvbnMtQ0QyNCsiLCAiQXN0cm8tQ0Q0NCsiLCAiUkctQ0QxODQrIiwgIlJHLUNEMTMzKyIsICJBc3Ryby1HbGFzdCsiLCJFbmRvdGhlbGlhbCIsIk5ldXJvbnMtQ0Q1NisiLCJOZXVyb25zLUNEMjQrQ0Q1NisiLCJPbGlnbyIsIkVwaXRoZWxpYWwiLCJNaXgiKQoKCiMgY2xlYXJlciBvdXRwdXQgLSBzaG91bGQgdHJ5IG1ha2UgYSBzdW1tYXJ5IG9mIHRoZSBhY2N1cmF5IAoKZm9yIChjZWxsIGluIGNlbGwudHlwZXMpIHsKICBoZ19vdXRwdXQgPC0gaHlwZXJnYXRlKHhwID0geG0udCwgZ2F0ZV92ZWN0b3IgPSBjbHVzdGVyLmxhYmVscywgbGV2ZWwgPSBjZWxsKQogIGdhdGluZ19wcmVkaWN0ZWQgPSBzdWJzZXRfbWF0cml4X2hnKGhnX291dHB1dCx4bS50KQogIGNvbmYudGFibGUgPC0gdGFibGUoaWZlbHNlKGdhdGluZ19wcmVkaWN0ZWQsICJHYXRlZC1pbiIsICJHYXRlZC1vdXQiKSwgaWZlbHNlKGNsdXN0ZXIubGFiZWxzID09ICBjZWxsLCBjZWxsLCAiT3RoZXJzIikpCiAgcHJpbnQoY2VsbCkKICBwcmludChjb25mLnRhYmxlKQogIHByaW50KGhnYXRlX3J1bGUoaGdfb3V0cHV0KSkKfQoKCiMgaGF2aW5nIHRoZSBtaXggY2VsbHMgaW4gbWFrZSBubyBkaWZmZXJlbmNlCgoKYGBgCgoKVHJ5IHdpdGggbWFpbiBncm91cHMgTmV1cm9uczEsIE5ldXJvbnMyLCBBc3RybywgUkcKCmBgYHtyfQoKSWRlbnRzKHNldS5xKSA8LSAnQmF0Y2gnCnNldSA8LSBzdWJzZXQoc2V1LnEsIGlkZW50cyA9IGMoIkFJVzAwMl8wMzA2IiwiQUlXMDAyXzAzMTdBIiwgIkFJVzAwMl8wMzE3QiIpKQoKCiMgZG93bnNhbXBlIHRvIGFib3V0IDIwMDAgY2VsbHMgc28gdGhhdCBoeXBlcmdhdGUgY2FuIHJ1bgojIHRoZXJlIGlzIGFuIG9wdGlvbiB0byBkb3duIHNhbXBsZSBwZXIgaWRlbnRpdHkgY2xhc3MKCiMgbm90IGVub3VnaCBvbGlnbyBpbiBvbmx5IEFJVwoKSWRlbnRzKHNldS5xKSA8LSAnbGFiZWxzLm1haW4uZ3JvdXBzJwpzZXUuZG93biA8LSBzdWJzZXQoeD0gc2V1LnEsIGRvd25zYW1wbGUgPSA1MDApCgpEaW1QbG90KHNldS5kb3duKQoKdGFibGUoc2V1LmRvd24kbGFiZWxzLm1haW4uZ3JvdXBzKQoKCgoKIyB0cnkgaHlwZXJnYXRlIGFnYWluIG9uIG9uZSBncm91cCAKaW5wdXQueG0gPSBhcy5tYXRyaXgoR2V0QXNzYXlEYXRhKHNldS5kb3duLCBzbG90ID0gJ2RhdGEnKSkKeG0udCA8LSB0KGlucHV0LnhtKQpjbHVzdGVyLmxhYmVscyA8LSBhcy52ZWN0b3Ioc2V1LmRvd24kbGFiZWxzLm1haW4uZ3JvdXBzKQoKI3RyeSBhbGwgYXQgb25jZQoKY2VsbC50eXBlcyA8LSBjKCJOZXVyb25zMSIsIk5ldXJvbnMyIiwiQXN0cm8iLCJSRyIsIkVuZG90aGVsaWFsIiwiT2xpZ28iLCJFcGl0aGVsaWFsIikKCgoKIyBjbGVhcmVyIG91dHB1dCAtIHNob3VsZCB0cnkgbWFrZSBhIHN1bW1hcnkgb2YgdGhlIGFjY3VyYXkgCgpmb3IgKGNlbGwgaW4gY2VsbC50eXBlcykgewogIGhnX291dHB1dCA8LSBoeXBlcmdhdGUoeHAgPSB4bS50LCBnYXRlX3ZlY3RvciA9IGNsdXN0ZXIubGFiZWxzLCBsZXZlbCA9IGNlbGwpCiAgZ2F0aW5nX3ByZWRpY3RlZCA9IHN1YnNldF9tYXRyaXhfaGcoaGdfb3V0cHV0LHhtLnQpCiAgY29uZi50YWJsZSA8LSB0YWJsZShpZmVsc2UoZ2F0aW5nX3ByZWRpY3RlZCwgIkdhdGVkLWluIiwgIkdhdGVkLW91dCIpLCBpZmVsc2UoY2x1c3Rlci5sYWJlbHMgPT0gIGNlbGwsIGNlbGwsICJPdGhlcnMiKSkKICBwcmludChjZWxsKQogIHByaW50KGNvbmYudGFibGUpCiAgcHJpbnQoaGdhdGVfcnVsZShoZ19vdXRwdXQpKQp9CgoKIyBoYXZpbmcgdGhlIG1peCBjZWxscyBpbiBtYWtlcyBubyBkaWZmZXJlbmNlCgoKCgpgYGAKCgpSZXBlYXQgd2l0aCBtb3JlIHBvcHVsYXRpb25zCgpgYGB7cn0KCiMgZGVmaW5lIG1vcmUgZ3JvdXBzCiNjbHVzdGVyLmlkcyA8LSBjKCJNaXgiLCJOZXVyb25zMSIsIkFzdHJvMSIsIlJHMSIsIlJHMiIsIk1peCIsIkFzdHJvMyIsIkFzdHJvMSIsIlJHMSIsIk1peCIsIkFzdHJvMyIsIkVuZG90aGVsaWFsIiwiQXN0cm8zIiwiTmV1cm9uczIiLCJOZXVyb25zMyIsIk5ldXJvbnMyIiwiQXN0cm8zIiwiTmV1cm9uczIiLCJOZXVyb25zMSIsIlJHMiIsIk9saWdvIiwiRXBpdGhlbGlhbCIsIk5ldXJvbnMzIikKCkRpbVBsb3Qoc2V1LnEsIGxhYmVsPSBUUlVFKQoKSWRlbnRzKHNldS5xKSA8LSAnY2VsbC50eXBlcycKc2V1LmRvd24gPC0gc3Vic2V0KHg9IHNldS5xLCBkb3duc2FtcGxlID0gODAwKQoKRGltUGxvdChzZXUuZG93bikKCnRhYmxlKHNldS5kb3duJGNlbGwudHlwZXMpCgoKCgojIHRyeSBoeXBlcmdhdGUgYWdhaW4gb24gb25lIGdyb3VwIAppbnB1dC54bSA9IGFzLm1hdHJpeChHZXRBc3NheURhdGEoc2V1LmRvd24sIHNsb3QgPSAnZGF0YScpKQp4bS50IDwtIHQoaW5wdXQueG0pCmNsdXN0ZXIubGFiZWxzIDwtIGFzLnZlY3RvcihzZXUuZG93biRjZWxsLnR5cGVzKQoKI3RyeSBhbGwgYXQgb25jZQoKY2VsbC50eXBlcyA8LSBjKCJOZXVyb25zMSIsIk5ldXJvbnMyIiwiTmV1cm9uczMiLCJBc3RybzEiLCJBc3RybzIiLCJBc3RybzMiLCJSRzEiLCJSRzIiLCJFbmRvdGhlbGlhbCIsIk9saWdvIiwiRXBpdGhlbGlhbCIsIk1peCIpCiMgMTEgcG9zc2libGUgcG9wdWxhdGlvbnMKCgoKIyBjbGVhcmVyIG91dHB1dCAtIHNob3VsZCB0cnkgbWFrZSBhIHN1bW1hcnkgb2YgdGhlIGFjY3VyYXkgCgpmb3IgKGNlbGwgaW4gY2VsbC50eXBlcykgewogIGhnX291dHB1dCA8LSBoeXBlcmdhdGUoeHAgPSB4bS50LCBnYXRlX3ZlY3RvciA9IGNsdXN0ZXIubGFiZWxzLCBsZXZlbCA9IGNlbGwpCiAgZ2F0aW5nX3ByZWRpY3RlZCA9IHN1YnNldF9tYXRyaXhfaGcoaGdfb3V0cHV0LHhtLnQpCiAgY29uZi50YWJsZSA8LSB0YWJsZShpZmVsc2UoZ2F0aW5nX3ByZWRpY3RlZCwgIkdhdGVkLWluIiwgIkdhdGVkLW91dCIpLCBpZmVsc2UoY2x1c3Rlci5sYWJlbHMgPT0gIGNlbGwsIGNlbGwsICJPdGhlcnMiKSkKICBwcmludChjZWxsKQogIHByaW50KGNvbmYudGFibGUpCiAgcHJpbnQoaGdhdGVfcnVsZShoZ19vdXRwdXQpKQp9CgoKCgoKYGBgCgpMb2FkIGluIGxpYnJhcmllcwpgYGB7cn0KcmVxdWlyZSgicmVzaGFwZTIiKSAjdmlzdWFsaXphdGlvbgpyZXF1aXJlKCJmbG93U3RhdHMiKSAjQWxpZ25tZW50IGZ1bmN0aW9ucwpyZXF1aXJlKCJzY2FsZXMiKSAjc2NhbGUgY29sb3VyIGludGVuc2l0eSBmb3IgdmlzdWFsaXphdGlvbgpyZXF1aXJlKCJkcGx5ciIpCmxpYnJhcnkoImh5cGVyZ2F0ZSIpCmxpYnJhcnkoIlNldXJhdCIpCgpgYGAKClJlYWQgaW4gdGhlIGRhdGEgZm9yIGdhdGluZwoKYGBge3J9CnNldS5yIDwtIHJlYWRSRFMoIi9Vc2Vycy9yaGFsZW5hdGhvbWFzL0RvY3VtZW50cy9EYXRhL0Zsb3dDeXRvbWV0cnkvUGhlbm9JRC9BbmFseXNpcy85TUJPL3ByZXByb19vdXRzL2NsdXN0ZXJzL0FsbGNlbGxMYWJsZXNNYXJjaDI1LlJkcyIpCgoKYGBgCgoKCgpJIm0gZ29pbmcgdG8gcnVuIHRoZSBoeXBlcmdhdGVzIGFnYWluIC0gbWF5YmUgbXVsdGlwbGUgdGltZXMgdG8gc2VlIGhvdyBjb25zaXRhdGFudCB0byBvdXRwdXQgd2lsbCBiZQoKYGBge3J9CgoKSWRlbnRzKHNldS5yKSA8LSAnY2VsbC50eXBlcycKaSA9IDMwMApzZXQuc2VlZChpKQpzZXUuZG93biA8LSBzdWJzZXQoeD0gc2V1LnIsIGRvd25zYW1wbGUgPSAyMDApCgoKIyB0cnkgaHlwZXJnYXRlIGFnYWluIG9uIG9uZSBncm91cCAKaW5wdXQueG0gPSBhcy5tYXRyaXgoR2V0QXNzYXlEYXRhKHNldS5kb3duLCBzbG90ID0gJ2RhdGEnKSkKeG0udCA8LSB0KGlucHV0LnhtKQpjbHVzdGVyLmxhYmVscyA8LSBhcy52ZWN0b3Ioc2V1LmRvd24kY2VsbC50eXBlcykKCiN0cnkgYWxsIGF0IG9uY2UKCmNlbGwudHlwZXMgPC0gYygiTmV1cm9uczEiLCJOZXVyb25zMiIsIk5ldXJvbnMzIiwiQXN0cm8xIiwiQXN0cm8yIiwiQXN0cm8zIiwiUkcxIiwiUkcyIiwiRW5kb3RoZWxpYWwiLCJPbGlnbyIsIkVwaXRoZWxpYWwiLCJNaXgiKQojIDExIHBvc3NpYmxlIHBvcHVsYXRpb25zCgoKCiMgY2xlYXJlciBvdXRwdXQgLSBzaG91bGQgdHJ5IG1ha2UgYSBzdW1tYXJ5IG9mIHRoZSBhY2N1cmF5IAoKZm9yIChjZWxsIGluIGNlbGwudHlwZXMpIHsKICBoZ19vdXRwdXQgPC0gaHlwZXJnYXRlKHhwID0geG0udCwgZ2F0ZV92ZWN0b3IgPSBjbHVzdGVyLmxhYmVscywgbGV2ZWwgPSBjZWxsKQogIGdhdGluZ19wcmVkaWN0ZWQgPSBzdWJzZXRfbWF0cml4X2hnKGhnX291dHB1dCx4bS50KQogIGNvbmYudGFibGUgPC0gdGFibGUoaWZlbHNlKGdhdGluZ19wcmVkaWN0ZWQsICJHYXRlZC1pbiIsICJHYXRlZC1vdXQiKSwgaWZlbHNlKGNsdXN0ZXIubGFiZWxzID09ICBjZWxsLCBjZWxsLCAiT3RoZXJzIikpCiAgcHJpbnQoY2VsbCkKICBwcmludChjb25mLnRhYmxlKQogIHByaW50KGhnYXRlX3J1bGUoaGdfb3V0cHV0KSkKfQoKCgoKYGBgCgoKClRyeSB1c2luZyB0aGUgc21hbGxlciBsYWJlbGVkIG9iamVjdCAtIHdpbGwgc3RpbGwgbmVlZCB0byBzdWJzZXQKQWxzbyBtYWtlIGdyb3VwaW5ncyBvZiBjZWxscwoKYGBge3J9CgpzZXUgPC0gcmVhZFJEUygiL1VzZXJzL3JoYWxlbmF0aG9tYXMvRG9jdW1lbnRzL0RhdGEvRmxvd0N5dG9tZXRyeS9QaGVub0lEL0FuYWx5c2lzLzlNQk8vcHJlcHJvX291dHNqYW4yMC05MDAwY2VsbHMvRmlndXJlMy9Mb3V2a242MERpZmZlcmVudENlbGxMYWJlbHMyMjAyMjAzMTguUmRzIikKCnNhdmVSRFMoc2V1LCIvVXNlcnMvcmhhbGVuYXRob21hcy9Eb2N1bWVudHMvRGF0YS9GbG93Q3l0b21ldHJ5L1BoZW5vSUQvQW5hbHlzaXMvOU1CTy9wcmVwcm9fb3V0c2phbjIwLTkwMDBjZWxscy9GaWd1cmUzL0xvdXZrbjYwRGlmZmVyZW50Q2VsbExhYmVsczIyMDIyMDMxOC5SZHMiKQoKQUIgPC0gYygiQ0QyNCIsIkNENTYiLCJDRDI5IiwiQ0QxNSIsIkNEMTg0IiwiQ0QxMzMiLCJDRDcxIiwiQ0Q0NCIsIkdMQVNUIiwiQVFQNCIsIkhlcGFDQU0iLCAiQ0QxNDBhIiwiTzQiKQoKI0RpbVBsb3Qoc2V1KQojRG9IZWF0bWFwKHNldSwgZmVhdHVyZXMgPSBBQikKCgoKCmBgYAoKClJ1biB3aXRoIGRpZmZlcmVudCBjdXRvZmYgb2YgY2VsbHMgaW4gZG93biBzYW1wbGluZwoKCmBgYHtyfQoKdW5pcXVlKHNldSRsYWJlbHM2KQoKIyBnZXQgdGhlIGNlbGwgdHlwZSBsYWJlbHMKCgpgYGAKClJlbGFiZWwgY2VsbCB0eXBlIGdyb3VwcwoKYGBge3J9CklkZW50cyhzZXUpIDwtICJsYWJlbHM2IgpjbHVzdGVyLmlkcyA8LSBjKCJNaXgiLCJSRzEiLCJNaXgiLCJOZXVyb25zMSIsIk5ldXJvbnMyIiwiQXN0cm8xIiwiQXN0cm8yIiwiUkcyIiwiTmV1cm9uMyIsIlJHMyIsIkVuZG90aGVsaWFsIiwiT2xpZ28iLCJQT0MiLCJFcGl0aGVsaWFsIikKCm5hbWVzKGNsdXN0ZXIuaWRzKSA8LSBsZXZlbHMoc2V1KQpzZXUgPC0gUmVuYW1lSWRlbnRzKHNldSwgY2x1c3Rlci5pZHMpCnNldSRnYXRpbmcuYWxsIDwtIElkZW50cyhzZXUpCgpEaW1QbG90KHNldSwgcmVkdWN0aW9uID0gInVtYXAiLCBsYWJlbCA9IFRSVUUsIGdyb3VwLmJ5ID0gJ2dhdGluZy5hbGwnLCByZXBlbCA9IFRSVUUpCgoKIyBub3cgZmV3ZXIgZ3JvdXBzCklkZW50cyhzZXUpIDwtICJsYWJlbHM2IgpjbHVzdGVyLmlkcyA8LSBjKCJNaXgiLCJSRzEiLCJNaXgiLCJOZXVyb25zMSIsIk5ldXJvbnMyIiwiQXN0cm8xIiwiQXN0cm8yIiwiUkcyIiwiTmV1cm9uczMiLCJSRzEiLCJFbmRvdGhlbGlhbCIsIk9saWdvIiwiT1BDIiwiRXBpdGhlbGlhbCIpCiMgbWVyZ2UgY2VsbHMgdGhhdCB3b24ndCBiZSB1c2VkIGZvciBnYXRpbmcKY2x1c3Rlci5pZHMgPC0gYygib3RoZXIiLCJSRzEiLCJvdGhlciIsIk5ldXJvbnMxIiwiTmV1cm9uczIiLCJBc3RybzEiLCJBc3RybzIiLCJSRzIiLCJOZXVyb25zMyIsIlJHMSIsIm90aGVyIiwib3RoZXIiLCJvdGhlciIsIm90aGVyIikKIyBhZGp1c3QgYmFzZWQgb24gaHlwZXJnYXRlIHJlc3VsdHMKY2x1c3Rlci5pZHMgPC0gYygib3RoZXIiLCJnbGlhIiwib3RoZXIiLCJOZXVyb25zMSIsIk5ldXJvbnMyIiwiZ2xpYSIsIkFzdHJvIiwiUkcyIiwiTmV1cm9uczMiLCJnbGlhIiwib3RoZXIiLCJvdGhlciIsIm90aGVyIiwib3RoZXIiKQoKCm5hbWVzKGNsdXN0ZXIuaWRzKSA8LSBsZXZlbHMoc2V1KQpzZXUgPC0gUmVuYW1lSWRlbnRzKHNldSwgY2x1c3Rlci5pZHMpCnNldSRnYXRpbmcubWFpbiA8LSBJZGVudHMoc2V1KQoKRGltUGxvdChzZXUsIHJlZHVjdGlvbiA9ICJ1bWFwIiwgbGFiZWwgPSBUUlVFLCBncm91cC5ieSA9ICdnYXRpbmcubWFpbicsIHJlcGVsID0gVFJVRSkKCiMgbm93IGZld2VyIGdyb3VwcwpJZGVudHMoc2V1KSA8LSAibGFiZWxzNiIKY2x1c3Rlci5pZHMgPC0gYygib3RoZXIiLCJSRyIsIm90aGVyIiwiTmV1cm9uczEiLCJOZXVyb25zMiIsIkFzdHJvIiwiQXN0cm8iLCJSRyIsIk5ldXJvbnMxIiwiUkciLCJvdGhlciIsIm90aGVyIiwib3RoZXIiLCJvdGhlciIpCgpuYW1lcyhjbHVzdGVyLmlkcykgPC0gbGV2ZWxzKHNldSkKc2V1IDwtIFJlbmFtZUlkZW50cyhzZXUsIGNsdXN0ZXIuaWRzKQpzZXUkZ2F0aW5nLjQgPC0gSWRlbnRzKHNldSkKCkRpbVBsb3Qoc2V1LCByZWR1Y3Rpb24gPSAidW1hcCIsIGxhYmVsID0gVFJVRSwgZ3JvdXAuYnkgPSAnZ2F0aW5nLjQnLCByZXBlbCA9IFRSVUUpCgoKCgoKYGBgCgoKCgoKYGBge3J9CklkZW50cyhzZXUpIDwtICdnYXRpbmcubWFpbicKaSA9IDMwMApzZXQuc2VlZChpKQpzZXUuZG93biA8LSBzdWJzZXQoeD0gc2V1LCBkb3duc2FtcGxlID0gNTAwKQoKCiMgdHJ5IGh5cGVyZ2F0ZSBhZ2FpbiBvbiBvbmUgZ3JvdXAgCmlucHV0LnhtID0gYXMubWF0cml4KEdldEFzc2F5RGF0YShzZXUuZG93biwgc2xvdCA9ICdkYXRhJykpCnhtLnQgPC0gdChpbnB1dC54bSkKY2x1c3Rlci5sYWJlbHMgPC0gYXMudmVjdG9yKHNldS5kb3duJGdhdGluZy5tYWluKQoKI3RyeSBhbGwgYXQgb25jZQpnYXRpbmcubWFpbi5jZWxsdHlwZXMgPC0gYygiUkcxIiwiUkcyIiwiTmV1cm9uczEiLCJOZXVyb25zMiIsIk5ldXJvbnMzIiwiQXN0cm8xIiwiQXN0cm8yIiwiRW5kb3RoZWxpYWwiLCJPbGlnbyIsIk9QQyIsIkVwaXRoZWxpYWwiKQoKIyBmb3IgZ2F0aW5nLjQKY2VsbC50eXBlcyA8LSBjKCJSRyIsIk5ldXJvbnMxIiwiTmV1cm9uczIiLCJBc3RybyIpCiMgZ2F0aW5nIG1vcmUgY2VsbCBwb3B1bGF0aW9ucyB0byB0cnkgYW5kIGdldCBiZXR0ZXIgYWNjdXJhY3kuICAKCmNlbGwudHlwZXMgPC0gYygiZ2xpYSIsIlJHMiIsIk5ldXJvbnMxIiwiTmV1cm9uczIiLCJOZXVyb25zMyIsIkFzdHJvIikKIyBub3RlIHRoYXQgUkcxIGFuZCBhc3RybzEgb3ZlcmxhcCBhbmQgUkcyIGFuZCBhc3RybyAyIG92ZXJsYXAgYSBsaXR0bGUgYml0CiMgUkcxIGFuZCBhc3RybyAxIGFyZSBoaWdoeSBvdmVybGFwcGluZyAtIG1lcmdlIHRvZ2V0aGVyCgojIGNsZWFyZXIgb3V0cHV0IC0gc2hvdWxkIHRyeSBtYWtlIGEgc3VtbWFyeSBvZiB0aGUgYWNjdXJheSAKCmZvciAoY2VsbCBpbiBjZWxsLnR5cGVzKSB7CiAgaGdfb3V0cHV0IDwtIGh5cGVyZ2F0ZSh4cCA9IHhtLnQsIGdhdGVfdmVjdG9yID0gY2x1c3Rlci5sYWJlbHMsIGxldmVsID0gY2VsbCkKICBnYXRpbmdfcHJlZGljdGVkID0gc3Vic2V0X21hdHJpeF9oZyhoZ19vdXRwdXQseG0udCkKICBjb25mLnRhYmxlIDwtIHRhYmxlKGlmZWxzZShnYXRpbmdfcHJlZGljdGVkLCAiR2F0ZWQtaW4iLCAiR2F0ZWQtb3V0IiksIGlmZWxzZShjbHVzdGVyLmxhYmVscyA9PSAgY2VsbCwgY2VsbCwgIk90aGVycyIpKQogIHByaW50KGNlbGwpCiAgcHJpbnQoY29uZi50YWJsZSkKICBwcmludChoZ2F0ZV9ydWxlKGhnX291dHB1dCkpCiAgIyB2aXN1YWxpemUgdGhlIHByZWRpY3RlZCBjZWxscyAKICBwcmVkaWN0ZWQuY2VsbC50eXBlID0gcGFzdGUoY2VsbCwiZ2F0ZWQiLHNlcD0iLiIpCiAgc2V1LmRvd24gPC0gQWRkTWV0YURhdGEob2JqZWN0PXNldS5kb3duLCBtZXRhZGF0YT1nYXRpbmdfcHJlZGljdGVkLCBjb2wubmFtZSA9IHByZWRpY3RlZC5jZWxsLnR5cGUgKQogIHByaW50KERpbVBsb3Qoc2V1LmRvd24sIGdyb3VwLmJ5ID0gcHJlZGljdGVkLmNlbGwudHlwZSwgc3BsaXQuYnkgPSAnZ2F0aW5nLm1haW4nKSkKICAKICAKICAKfQoKCiMgaHlwZXJnYXRlKCB4cCA9IG1hdHJpeCwgZ2F0ZV92ZWN0b3IgPSBsYWJlbHMsIGxldmVsID0gdGhpbmcgdG8gZ2F0ZSkKCgoKCmBgYAoKVGhlIGdsaWEgaXMgb25seSA1MC81MCBhbmQgbm8gZ29vZApUaGUgb3RoZXIgY2VsbCB0eXBlIGFjY3VyYWN5IGlzIGhpZ2gKCgoKCgpUcnkgcGxvdHRpbmcgdGhlIHJlc3VsdHMgdG8gc2VlIHdoZXJlIHRoZSBsYWJlbGxlZCBjZWxscyBlbmQgdXAKCmBgYHtyfQojIGhvdyB0byBzZWUgdGhhdCBnYXRlZCBwb3B1bGF0aW9ucz8/PwojIGdhdGluZyBwcmVkaWN0ZWQgaXMgYSBsb2dpY2FsIGlmIGl0IGlzIGluIG9yIG5vdApsZW5ndGgoZ2F0aW5nX3ByZWRpY3RlZCkKZGltKHNldS5kb3duKQoKIyBhZGQgdGhlIGxvZ2ljYWwgYXMgYSBtZXRhIGRhdGEgCnNldS5kb3duIDwtIEFkZE1ldGFEYXRhKG9iamVjdD1zZXUuZG93biwgbWV0YWRhdGE9Z2F0aW5nX3ByZWRpY3RlZCwgY29sLm5hbWUgPSAnZ2F0ZV9wcmVkaWN0ZWQnKQoKCgpEaW1QbG90KHNldS5kb3duLCBncm91cC5ieSA9ICdnYXRlX3ByZWRpY3RlZCcsIHNwbGl0LmJ5ID0gJ2dhdGluZy5tYWluJykKCgpgYGAKCgoKCgoKCgoKCgpJbnN0ZWFkIG9mIHN1YnNhbXBsaW5nIGluIGFkdmFuY2UgSSBjYW4gc2FtcGxlIHVzaW5nIGhnYXRlX3NhbXBsZSB0byBhbHNvIHNhbXBsZSBuZWdhdGl2ZSBldmVudHMuIFRoaXMganVzdCBnaXZlcyB5b3UgYW4gaWRlYSBvZiBob3cgbWFueSBjZWxscyB5b3UgbmVlZCB0byBzYW1wbGUKCmBgYHtyfQojIHRoaXMgaXMganVzdCB0byBjaGVjayB0aGUgZnJlcXVlbmN5IG9mIGV2ZW50cwoKaW5wdXQueG0gPSBhcy5tYXRyaXgoR2V0QXNzYXlEYXRhKHNldSwgc2xvdCA9ICdkYXRhJykpCnhtLnQgPC0gdChpbnB1dC54bSkKY2x1c3Rlci5sYWJlbHMgPC0gYXMudmVjdG9yKHNldSRnYXRpbmcubWFpbikKCiMgaHlwZXJnYXRlKCB4cCA9IG1hdHJpeCwgZ2F0ZV92ZWN0b3IgPSBsYWJlbHMsIGxldmVsID0gdGhpbmcgdG8gZ2F0ZSkKc2FtcGxlID0gaGdhdGVfc2FtcGxlKGdhdGVfdmVjdG9yID0gY2x1c3Rlci5sYWJlbHMsIGxldmVsID0gIkFzdHJvMSIsIHNpemU9MTAwMCkKCgp0YWIgPSB0YWJsZShpZmVsc2Uoc2FtcGxlLCAiSW4iLCAiT3V0IiksIGlmZWxzZShjbHVzdGVyLmxhYmVscyA9PSAiQXN0cm8xIiwgIlBvc2l0aXZlIHBvcC4iLCAiTmVnYXRpdmUgcG9wLiIpKQp0YWJbMSwgXS9jb2xTdW1zKHRhYikgICMjIEZyYWN0aW9uIG9mIHN1YnNhbXBsZWQgZXZlbnRzIGZvciBwb3NpdGl2ZSBhbmQgbmVnYXRpdmUgcG9wdWxhdGlvbnMKCmBgYAoKCgoK